package com.smalluz.ad.modules.ks.api.impl;

import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;

import org.apache.commons.lang3.StringUtils;

import com.smalluz.ad.modules.common.config.MediaConfigStorage;
import com.smalluz.ad.modules.common.enums.MediaApiUrl;
import com.smalluz.ad.modules.common.exception.ApiException;
import com.smalluz.ad.modules.common.util.json.JacksonUtils;
import com.smalluz.ad.modules.ks.bean.KsRefreshTokenRequest;
import com.smalluz.ad.modules.ks.enums.ErrorCodeEnum;
import com.smalluz.ad.modules.ks.result.KsAccessTokenResult;
import com.smalluz.ad.modules.oe.bean.OAuth2TokenRequest;

import lombok.extern.slf4j.Slf4j;

/**
 * @author biteam
 * @Title: KsServiceOkHttpImpl
 * @Description: TODO(描述)
 * @site http://www.smalluz.com/
 * @email 510711793@qq.com
 * @date 2022-06-21 20:37
 */
@Slf4j
public class KsServiceOkHttpImpl extends BaseKsServiceImpl {

 

    @Override
    public String getAccessToken() {
        return this.getAccessToken(false);
    }

    @Override
    public String getAccessToken(Boolean forceRefresh) {
        final MediaConfigStorage config = this.getMediaConfigStorage();
        if (config.isAccessTokenValid() && !forceRefresh) {
            return config.getAccessToken();
        }

        Lock lock = config.getAccessTokenLock();
        boolean locked = false;
        try {
            do {
                locked = lock.tryLock(100, TimeUnit.MILLISECONDS);
                if (!forceRefresh && config.isAccessTokenValid()) {
                    return config.getAccessToken();
                }
            } while (!locked);
        KsAccessTokenResult acRes = this.getAccessTokenEntity();
        if (acRes != null && acRes.getData() != null && StringUtils.isNoneBlank(acRes.getData().getAccessToken())) {
            return acRes.getData().getAccessToken();
        }

        return "";

        }  catch (InterruptedException e) {
            throw new ApiException(e);
        } finally {
            if (locked) {
                lock.unlock();
            }
        }
    }

    @Override
    public String refreshAccessToken() {
        final MediaConfigStorage config = this.getMediaConfigStorage();

        KsRefreshTokenRequest refreshTokenRequest = KsRefreshTokenRequest.builder()
                .appid(config.getAppId())
                .secret(config.getSecret())
                .refreshToken(config.getRefreshAccessToken())
                .build();
        
        log.info("~~~~刷新token接口入参：{}",JacksonUtils.bean2Jsn(refreshTokenRequest));
        
        String responseContent = this.postNoToken(MediaApiUrl.KsOAuth2.OAUTH2_OPEN_API_REFRESH_ACCESS_TOKEN, refreshTokenRequest);
        
        log.info("~~~~刷新token接口返回结果：{}",responseContent);
        KsAccessTokenResult tokenResult = KsAccessTokenResult.fromJson(responseContent);
        
        //更新token存储机制
        config.updateAccessKsToken(tokenResult);
        try {
            //记录刷新token错误的日志
            if (!ErrorCodeEnum.CommonEnum.OK.getCode().equals(tokenResult.getCode())) {
              
            }
        } catch (Exception e) {
            
        }


        return responseContent;

    }

    @Override
    public String post(MediaApiUrl url, Object object) throws ApiException {
        return this.post(this.getAccessToken(), url.getKsUrl(), JacksonUtils.bean2Jsn(object));
    }

    public String postNoToken(MediaApiUrl url, Object object) throws ApiException {
        return this.postNoToken(url.getKsUrl(), JacksonUtils.bean2Jsn(object));
    }

    @Override
    public String get(MediaApiUrl url, Object object) throws ApiException {
        return this.get(this.getAccessToken(), url.getKsUrl(), JacksonUtils.bean2Jsn(object));
    }

    @Override
    public KsAccessTokenResult getAccessTokenEntity() {
        final MediaConfigStorage config = this.getMediaConfigStorage();

        log.info("~~~~设置的配置参数 advertiserId： {}", config.getAdvertiserId());
        log.info("~~~~设置的配置参数 appid： {}", config.getAppId());
        log.info("~~~~设置的配置参数 secret： {}", config.getSecret());
        log.info("~~~~设置的配置参数 authcode： {}", config.getAuthCode());
        String responseContent = "";
        if (StringUtils.isNotBlank(config.getRefreshAccessToken()) && config.isRefreshAccessTokenValid()) {

            log.info("~~~~走刷新参数： {}", config.getRefreshAccessToken());
            responseContent = this.refreshAccessToken();
        } else {
            responseContent = this.postNoToken(MediaApiUrl.KsOAuth2.OAUTH2_OPEN_API_OAUTH2_ACCESS_TOKEN, OAuth2TokenRequest.builder()
                    .appid(config.getAppId())
                    .secret(config.getSecret())
                    .authCode(config.getAuthCode())
                    .build());
        }

        log.info("~~~~调用接口返回： {}", responseContent);
        KsAccessTokenResult acRes = KsAccessTokenResult.fromJson(Objects.requireNonNull(responseContent));


        

        return acRes;
    }
}
